package service

import (
	"errors"
	"time"

	"pool/pool_backend/internal/models"
	"pool/pool_backend/internal/repository"
	"pool/pool_backend/pkg/logger"
)

// UserService 用户服务接口
type UserService interface {
	// GetOrCreateUser 获取或创建用户
	GetOrCreateUser(address string) (*models.User, error)
	// GetUserInfo 获取用户信息
	GetUserInfo(address string) (*models.UserInfo, error)
	// BindInviter 绑定邀请人
	BindInviter(userAddress, inviterAddress string) error
	// GetSubUsers 获取下级用户
	GetSubUsers(address string) ([]*models.SubUser, error)
	// GetUserStats 获取用户统计
	GetUserStats() (int64, int64, error)
	// IsBinded 判断用户是否已经绑定过邀请人
	IsBinded(address string) (bool, error)
}

// userServiceImpl 用户服务实现
type userServiceImpl struct {
	userRepo  repository.UserRepository
	claimRepo repository.ClaimRepository
}

// NewUserService 创建用户服务
func NewUserService(userRepo repository.UserRepository, claimRepo repository.ClaimRepository) UserService {
	return &userServiceImpl{
		userRepo:  userRepo,
		claimRepo: claimRepo,
	}
}

// GetOrCreateUser 获取或创建用户
func (s *userServiceImpl) GetOrCreateUser(address string) (*models.User, error) {
	// 检查地址格式
	if len(address) != 42 || address[:2] != "0x" {
		return nil, errors.New("invalid address format")
	}

	// 尝试获取用户
	user, err := s.userRepo.GetUserByAddress(address)
	if err != nil {
		logger.ErrorF("Failed to get user: %v", err)
		return nil, err
	}

	// 如果用户不存在，则创建用户
	if user == nil {
		// 使用1970-01-01作为默认日期，避免MySQL严格模式错误
		defaultTime := time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC)
		user = &models.User{
			Address:     address,
			LastCheckIn: defaultTime,
			LastCheck:   defaultTime,
		}
		err = s.userRepo.CreateUser(user)
		if err != nil {
			logger.ErrorF("Failed to create user: %v", err)
			return nil, err
		}
	}

	return user, nil
}

// GetUserInfo 获取用户信息
func (s *userServiceImpl) GetUserInfo(address string) (*models.UserInfo, error) {
	// 获取用户
	user, err := s.userRepo.GetUserByAddress(address)
	if err != nil {
		logger.ErrorF("Failed to get user: %v", err)
		return nil, err
	}
	if user == nil {
		return nil, errors.New("user not found")
	}

	// 获取邀请用户数
	inviteeCount, err := s.userRepo.GetInviteeCount(address)
	if err != nil {
		logger.ErrorF("Failed to get invitee count: %v", err)
		return nil, err
	}

	// 构建UserInfo
	userInfo := &models.UserInfo{
		User:         *user,
		InviteeCount: inviteeCount,
	}

	return userInfo, nil
}

// BindInviter 绑定邀请人
func (s *userServiceImpl) BindInviter(userAddress, inviterAddress string) error {
	// 检查地址格式
	if len(userAddress) != 42 || userAddress[:2] != "0x" {
		return errors.New("invalid user address format")
	}
	if len(inviterAddress) != 42 || inviterAddress[:2] != "0x" {
		return errors.New("invalid inviter address format")
	}

	// 检查是否自己邀请自己
	if userAddress == inviterAddress {
		return errors.New("cannot invite yourself")
	}

	// 获取或创建用户
	user, err := s.GetOrCreateUser(userAddress)
	if err != nil {
		logger.ErrorF("Failed to get or create user: %v", err)
		return err
	}

	// 检查用户是否已经绑定过邀请人
	if user.ParentID != "" {
		return errors.New("inviter already set")
	}

	// 获取或创建邀请人
	inviter, err := s.GetOrCreateUser(inviterAddress)
	if err != nil {
		logger.ErrorF("Failed to get or create inviter: %v", err)
		return err
	}

	// 设置邀请关系
	user.ParentID = inviterAddress

	// 设置祖先关系
	ancestors := inviterAddress
	if inviter.Ancestors != "" {
		ancestors = inviterAddress + "," + inviter.Ancestors
	}
	user.Ancestors = ancestors

	// 更新用户
	err = s.userRepo.UpdateUser(user)
	if err != nil {
		logger.ErrorF("Failed to update user: %v", err)
		return err
	}

	return nil
}

// GetSubUsers 获取下级用户
func (s *userServiceImpl) GetSubUsers(address string) ([]*models.SubUser, error) {
	// 检查地址格式
	if len(address) != 42 || address[:2] != "0x" {
		return nil, errors.New("invalid address format")
	}

	// 获取下级用户
	subUsers, err := s.userRepo.GetSubUsers(address)
	if err != nil {
		logger.ErrorF("Failed to get sub users: %v", err)
		return nil, err
	}

	return subUsers, nil
}

// GetUserStats 获取用户统计
func (s *userServiceImpl) GetUserStats() (int64, int64, error) {
	// 获取用户总数
	userCount, err := s.userRepo.GetUserCount()
	if err != nil {
		logger.ErrorF("Failed to get user count: %v", err)
		return 0, 0, err
	}

	// 获取总领取数量
	totalClaimed, err := s.claimRepo.GetTotalClaimed()
	if err != nil {
		logger.ErrorF("Failed to get total claimed: %v", err)
		return 0, 0, err
	}

	return userCount, totalClaimed, nil
}

func (s *userServiceImpl) IsBinded(address string) (bool, error) {
	// 检查地址格式
	if len(address) != 42 || address[:2] != "0x" {
		return false, errors.New("invalid address format")
	}
	// 获取用户
	user, err := s.userRepo.GetUserByAddress(address)
	if err != nil {
		logger.ErrorF("Failed to get user: %v", err)
		return false, err
	}
	
	// 如果用户不存在，返回未绑定
	if user == nil {
		return false, nil
	}
	
	// 如果用户的ParentID为空，表示未绑定
	if user.ParentID == "" {
		return false, nil
	}
	
	// 获取用户的邀请人
	inviter, err := s.userRepo.GetUserByAddress(user.ParentID)
	if err != nil {
		logger.ErrorF("Failed to get inviter: %v", err)
		return false, err
	}
	
	// 判断邀请人是否存在
	if inviter == nil {
		return false, nil
	}
	
	return true, nil
}